package com.wzw.springboot.principle.mvc.argumentresolver;

import com.wzw.springboot.principle.annotation.MvcExt;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import java.util.Map;

/**
 * 对controller方法上的参数进行解析的解析器，如：JSON的RequestResponseBodyMethodProcessor
 * 自定义可使用的场景：同意解析一个类型的值，让方法上可以直接接收。
 * 这种方式可以说更加通用的参数解析方法，Advice类型的方法只是Spring对JSON类型的数据又进行了一次处理
 * 普通的： 转换器 -> 参数解析
 * JSON：转换器 -> 参数解析 -> Advice接口读写数据
 * <p>
 * 也是在WebMvcConfigurationSupport.requestMappingHandlerAdapter()被初始化，只不过不是自动装配了。是由其子类实现，一般会注册到WebMvcConfigurer中
 *
 * @author Wangzhiwen
 */
public class CustomizedHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {

    /**
     * 是否支持
     *
     * @param parameter 包装了Method反射对象
     * @return true 支持 false 不支持
     */
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(MvcExt.class);
    }

    /**
     * 解析请求内容并返回一个需要的对象，这样在controller上直接加上这个类型，就会被自动绑定上去了
     *
     * @param parameter     包装了Method反射对象
     * @param mavContainer  视图容器
     * @param webRequest    请求对象Request
     * @param binderFactory web数据绑定工程
     * @return 需要的对象
     * @throws Exception 异常
     */
    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        // 比如返回一个通用的对象：User
        String header = webRequest.getHeader("Token");
        Map<String, String[]> parameterMap = webRequest.getParameterMap();
        return "xxx";
    }
}
